package com.tanhua.dubbo.huanxin.service;

import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import com.tanhua.dubbo.huanxin.exception.UnauthorizedException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

/**
 * 对于环信通用的请求的封装
 */
@Service
@Slf4j
public class RequestService {

    @Autowired
    private TokenService tokenService;

    @Retryable(value = UnauthorizedException.class, maxAttempts = 5, backoff = @Backoff(delay = 2000L, multiplier = 2))
    public HttpResponse execute(Method method, String url, String jsonParam) {
        HttpRequest httpRequest;
        switch (method) {
            case GET: {
                httpRequest = HttpRequest.get(url);
                break;
            }
            case POST: {
                httpRequest = HttpRequest.post(url);
                break;
            }
            case PUT: {
                httpRequest = HttpRequest.put(url);
                break;
            }
            case DELETE: {
                httpRequest = HttpRequest.delete(url);
                break;
            }
            default: {
                return null;
            }
        }

        HttpResponse httpResponse = httpRequest
                .header(Header.CONTENT_TYPE, "application/json") //请求头
                .header(Header.AUTHORIZATION, "Bearer " + this.tokenService.getToken())//请求头携带token
                .body(jsonParam) //请求参数
                .timeout(20000) //请求超时时间
                .execute();//执行请求

        if (httpResponse.getStatus() == 401) {
            // token失效
            // 需要重新刷新token，进行重试
            this.tokenService.refreshToken();
            throw new UnauthorizedException(url, jsonParam, method);
        }

        return httpResponse;
    }

    @Recover //全部重试失败后执行
    public HttpResponse recover(UnauthorizedException e) {
        //重试全部失败，基本上程序已经无法自己恢复了
        //就需要人工介入了
        //TODO 需要给项目负责人发出通知：可以是短信或邮件
        log.error("重试获取token全部失败，请人工进行检查！ url = {}, body = {}, method = {}",
                e.getUrl(), e.getBody(), e.getMethod());
        return null; //返回默认
    }

}
